using System;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;

namespace Triton.Common
{
	public static class FastObjectFactory
	{
		public delegate object CreateObject(IntPtr ptr);

		private static readonly Hashtable hashtable_0 = Hashtable.Synchronized(new Hashtable());

		private static readonly Type type_0 = typeof(CreateObject);

		public static T CreateObjectInstance<T>(IntPtr ptr)
		{
			return (T)CreateObjectFactory<T>()(ptr);
		}

		public static CreateObject CreateObjectFactory<T>()
		{
			return CreateObjectFactory(typeof(T));
		}

		public static CreateObject CreateObjectFactory(Type t)
		{
			CreateObject createObject = hashtable_0[t] as CreateObject;
			if (createObject == null)
			{
				lock (hashtable_0.SyncRoot)
				{
					createObject = hashtable_0[t] as CreateObject;
					if (createObject != null)
					{
						return createObject;
					}
					DynamicMethod dynamicMethod = new DynamicMethod("DM$OBJ_FACTORY_" + t.Name, t, new Type[1] { typeof(IntPtr) }, restrictedSkipVisibility: true);
					ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
					iLGenerator.Emit(OpCodes.Ldarg_0);
					ConstructorInfo constructor = t.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(IntPtr) }, null);
					if (constructor == null)
					{
						return null;
					}
					iLGenerator.Emit(OpCodes.Newobj, constructor);
					iLGenerator.Emit(OpCodes.Ret);
					createObject = (CreateObject)dynamicMethod.CreateDelegate(type_0);
					hashtable_0.Add(t, createObject);
					return createObject;
				}
			}
			return createObject;
		}
	}
}
